package com.cgwx.commonutils.math;

/**
 * @author GaoWei
 * @Date 2021/8/6 - 9:49
 */
public final class PascalsTriangle {
    private static double[][] pt = { { 1.0D } };

    public static synchronized double nCr(int n, int r) {
        if ((r < 0) || (r > n)) {
            return 0.0D;
        }
        if (n >= pt.length)
        {
            int d = 2 * pt.length;
            double[][] pt2;
            if (n > d) {
                pt2 = new double[n + 1][];
            } else {
                pt2 = new double[d + 1][];
            }
            System.arraycopy(pt, 0, pt2, 0, pt.length);
            for (int i = pt.length; i < pt2.length; i++)
            {
                pt2[i] = new double[i / 2 + 1];

                pt2[i][0] = 1.0D;
                for (int j = 1; j < pt2[i].length; j++)
                {
                    double x = pt2[(i - 1)][(j - 1)];
                    if (j < pt2[(i - 1)].length) {
                        x += pt2[(i - 1)][j];
                    } else {
                        x *= 2.0D;
                    }
                    pt2[i][j] = x;
                }
            }
            pt = pt2;
        }
        if (2 * r > n) {
            r = n - r;
        }
        return pt[n][r];
    }

    public static synchronized void reset()
    {
        pt = new double[][] { { 1.0D } };
    }
}
